package cn.android.support.v7.lib.sin.crown.base;

import android.Manifest;
import android.app.Activity;
import android.content.ContentResolver;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.graphics.Matrix;
import android.hardware.Camera;
import android.media.ExifInterface;
import android.media.MediaMetadataRetriever;
import android.net.Uri;
import android.os.Build;
import android.provider.MediaStore;
import android.provider.Settings;
import android.support.annotation.NonNull;
import android.support.design.widget.Snackbar;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.FileProvider;
import android.util.Log;
import android.view.View;
import android.widget.TextView;


import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

import cn.android.support.v7.lib.sin.crown.R;
import cn.android.support.v7.lib.sin.crown.utils.AssetsUtils;
import cn.android.support.v7.lib.sin.crown.utils.FileUtils;
import cn.android.support.v7.lib.sin.crown.utils.NumberUtils;


/**
 * 直接调用里面的 相册【photo()】，拍照【camera()】，剪辑【crop(File file)】方法。实现回调函数即可。
 * 亲测可用，兼容7.0(版本号24)【系统不支持多图片选择，多图片选择器需另外开发。多图片选择器开发肯定是需要SD卡的读取权限才能开发。】
 * Created by 彭治铭 on 2017/9/10.
 */

public abstract class BasePhotoActivity extends BaseActivity {

    //文件路径【相机不能使用私有目录，必须使用sd卡。这个sd卡区域，不需要权限哦】
    public String getAppCaclePath() {
        //defaultConfig {
        //targetSdkVersion 23//getExternalFilesDir才能正常访问，无需权限。但是如果是22及以下。就需要开启SD卡读取权限。
        //}
        //return getExternalFilesDir(Environment.DIRECTORY_PICTURES).getAbsolutePath();
        return getApplicationContext().getFilesDir().getAbsoluteFile().getAbsolutePath();
    }

    //图片尺寸
    protected int BITMAP_WIDTH = 720;
    int quality = 80;//图片质量

    //打开相册【不需要任何权限，亲测百分百可用】,系统会跳出一个相册选择框。无法跳过这一步【无解】。
    //只能选择一个。系统没有多选。都是单选。
    public void photo() {
        try {
            Intent intent = new Intent();
            //i.setType("image/jpeg");//一般拍照的格式就是jpeg【jpeg就是.jpg】
            intent.setType("image/*");
            intent.putExtra("return-data", true);
            intent.setAction(Intent.ACTION_PICK);//不能再调用intent.addCategory(),会出错。
            intent.setData(MediaStore.Images.Media.EXTERNAL_CONTENT_URI);//必不可少，不然图片返回错误
            startActivityForResult(intent, Activity.DEFAULT_KEYS_SHORTCUT);//自定义相册标志
        } catch (Exception e) {
            Log.e("test", "相册崩坏" + e.getMessage());
        }
    }

    int VIDEO_PHOTO = 3032;//跳转本地视频标志。

    //打开系统本地视频,只能选择一个。系统没有多选。都是单选。
    //【不需要任何权限，亲测百分百可用】
    //本地视频，一般只能识别mp4和3gp格式。
    public void video() {
        try {
            Intent intent = new Intent();
            intent.setType("video/*");
            intent.putExtra("return-data", true);
            intent.setAction(Intent.ACTION_PICK);//不能再调用intent.addCategory(),会出错。
            //亲测，不加这个也能获取流。也能获取文件名。只能获取文件名。无法获取标题路径和ID等。最好不要加这个，加了这个就没有本地视频选项，只有相册【相册里面也是视频】。
            //intent.setData(MediaStore.Video.Media.EXTERNAL_CONTENT_URI);//不加这个，也能获取流，获取文件名。还能有本地视频选项。加了这句就没有本地视频选项。
            //以下两个addFlags必不可少。【以防万一出错】
            intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
            intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
            intent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, 1);

            startActivityForResult(intent, VIDEO_PHOTO);//自定义相册标志
        } catch (Exception e) {
            Log.e("test", "相册崩坏2" + e.getMessage());
        }
    }

    Uri fileUri = null;// 相机拍照时创建的Uri链接,fileUri.getPath()获取拍照图片路径

    //相机拍照【需要相机权限,如果清单里不写明相机权限,部分设备默认是开启。但是有的设备就不行，可能异常奔溃。所以保险还是在清单里加上权限声明】
    public void camera() {
        perMissionMode = perMissionModeCamera;
        if (requestPermissionsCamera(this)) {
            try {
                Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
                File file = createFile(getAppCaclePath());//相机拍摄的照片位置。不使用SD卡。这样就不需要SDK权限。
                if (Build.VERSION.SDK_INT >= 23) {//7.0及以上版本(版本号24),为了兼容6.0(版本号23)，防止6.0也可能会有这个问题。
                    //getPackageName()和${applicationId}显示的都是当前应用的包名。无论是在library还是moudle中，都是一样的。都显示的是当前应用moudle的。与类库无关。请放心使用。
                    fileUri = FileProvider.getUriForFile(this, getPackageName() + ".provider",//与android:authorities="${applicationId}.provider"对应上
                            file);
                } else {
                    fileUri = Uri.fromFile(file);
                }
                //以下两个addFlags必不可少。【以防万一出错】
                intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
                intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
                intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri);//必不可少
                startActivityForResult(intent, Activity.DEFAULT_KEYS_DIALER);//自定义相机标志
            } catch (Exception e) {
                // TODO: handle exception
                Log.e("test", "相机崩坏" + e.getMessage());
            }
        }
    }

    File cameraVideoFile = null;//记录相机视频拍摄的文件。使用fileUri.getPath()对于图片还行。对于视频无法正确返回其路径。所以只能自己记录保存文件路径。
    int VIDEO_CAPTURE = 2042;//跳转视频拍摄标志。

    //跳转系统相机视频拍摄【需要相机权限】,手机拍摄的格式一般都是mp4的格式。
    public void cameraVideo() {
        //相机拍摄还是拍照。都需要申请相机权限。
        perMissionMode = perMissionModeVideo;
        if (requestPermissionsCamera(this)) {
            Uri fileUri = null;
            String path = getAppCaclePath();//相机拍摄的照片位置。不使用SD卡。使用自己应用私有SD卡目录，这样就不需要外部的SD卡权限。
            cameraVideoFile = new File(path + "/" + System.currentTimeMillis() + ".mp4");//视频拍摄基本都是MP4格式。每次都以当前毫秒数重新创建拍摄文件。
            if (cameraVideoFile.exists() == false) {
                try {
                    cameraVideoFile.createNewFile();
                } catch (IOException e) {
                    Log.e("test", "文件生成异常:\t" + e.getMessage());
                }
            }
            if (!cameraVideoFile.exists()) {
                return;//文件不存在。就不执行。
            }
            if (Build.VERSION.SDK_INT >= 23) {//7.0及以上版本(版本号24),为了兼容6.0(版本号23)，防止6.0也可能会有这个问题。
                //getPackageName()和${applicationId}显示的都是当前应用的包名。无论是在library还是moudle中，都是一样的。都显示的是当前应用moudle的。与类库无关。请放心使用。
                fileUri = FileProvider.getUriForFile(this, getPackageName() + ".provider",//与android:authorities="${applicationId}.provider"对应上
                        cameraVideoFile);
            } else {
                fileUri = Uri.fromFile(cameraVideoFile);
            }
            Intent intent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);
            //以下两个addFlags必不可少。【以防万一出错】
            intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
            intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
            intent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, 1);
            intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri);//必不可少。拍摄视频使用自定义文件路径。如果没有。默认使用系统的路径。那样就需要申请SD卡权限。不使用系统默认的。
            startActivityForResult(intent, VIDEO_CAPTURE);

        }
    }


    Uri cropUri = null;
    File cropFile = null;

    //图片剪辑【可以在相册，拍照回调成功后调用哦。】,兼容7.0。模拟器上没有上面效果。6.0的真机都没问题。7.0的真机没有测试。
    //w:h 宽和高的比率
    public void crop(File file, int w, int h) {
        cropFile = file;
        Intent intent = new Intent("com.android.camera.action.CROP");
        if (Build.VERSION.SDK_INT >= 23) {//7.0及以上版本(版本号24),为了兼容6.0(版本号23)，防止6.0也可能会有这个问题。
            //相机里面也使用了这个，多次使用不会出错。可以重复使用，不冲突。
            fileUri = FileProvider.getUriForFile(this, getPackageName() + ".provider",//与android:authorities="${applicationId}.provider"对应上
                    file);
        } else {
            fileUri = Uri.fromFile(file);
        }
        //以下两个addFlags必不可少。
        intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
        intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
        //告诉系统需要裁剪,以下這兩个参数可有可无，为了兼容性，两个都设置成true,以防万一。
        intent.putExtra("crop", "true");
        intent.putExtra("scale", true);//缩放功能禁止不了，系统裁剪，肯定自带缩放的功能。无法固定大小，只能固定宽高比例裁剪。总之缩放功能禁止不了，无论你设置true还是false都一样。自带缩放。
        //width:height 裁剪框的宽高比
        //intent.putExtra("aspectX", 1);
        //intent.putExtra("aspectY", 1);
        intent.putExtra("aspectX", w);
        intent.putExtra("aspectY", h);
        //裁剪的宽和高。具体的数值。
        //intent.putExtra("outputX", 600);
        //intent.putExtra("outputY", 300);

        intent.putExtra("return-data", false);
        intent.putExtra("noFaceDetection", true);//去除默认的人脸识别，否则和剪裁匡重叠
        intent.setDataAndType(fileUri, "image/*");//读取的uri,即要裁剪的uri
        cropUri = Uri.fromFile(file);//和上面的uri不是同一个uri,但是文件可以指向同一个。在此，剪辑图片和保存后的图片指向同一个文件。防止图片重复。保存一个即可。图片被裁剪之后，会直接对该文件产生影响。
        intent.putExtra(MediaStore.EXTRA_OUTPUT, cropUri);//截图保存的uri必须使用Uri.fromFile()
        intent.putExtra("outputFormat", Bitmap.CompressFormat.JPEG.toString());//输出格式
        startActivityForResult(intent, Activity.DEFAULT_KEYS_DISABLE);//自定义剪辑标志
    }

    //获取相册图片路径
    public String getPhotoPath(Activity activtiy, Intent data) {
        String photoPath = null;
        try {
            Uri uri = data.getData();
            // 获取相册图片路径
            String[] proj = {MediaStore.Images.Media.DATA};
            // 好像是android多媒体数据库的封装接口，具体的看Android文档
            Cursor cursor = null;
            if (Build.VERSION.SDK_INT >= 19) {//4.4版本
                //managedQuery()现在已经被getContentResolver().query()替代了，不过它们的参数都是一样的。效果也是一样的。
                cursor = getContentResolver().query(uri, proj, null, null, null);
            } else {
                //低版本
                cursor = activtiy.managedQuery(uri, proj, null, null, null);
            }
            // 按我个人理解 这个是获得用户选择的图片的索引值
            int column_index = cursor
                    .getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
            // 将光标移至开头 ，这个很重要，不小心很容易引起越界
            cursor.moveToFirst();
            // 最后根据索引值获取图片路径
            photoPath = cursor.getString(column_index);
            // bm = BitmapFactory.decodeFile(path);
        } catch (Exception e) {
            // TODO: handle exception
            Log.e("test", "相册图片路径获取失败" + e.getMessage());
        }
        return photoPath;
    }

    //创建文件,路径默认可以使用 BITMAP_PATH
    public File createFile(String path) {
        if (path == null) {
            path = getAppCaclePath();
        }
        if (path.trim().equals("")) {
            path = getAppCaclePath();
        }
        File fileParent = new File(path);
        if (fileParent.exists() == false) {
            fileParent.mkdirs();
        }
        File file = null;
        file = new File(path + "/" + System.currentTimeMillis() + ".jpg");
        if (file.exists() == false) {
            try {
                file.createNewFile();
            } catch (IOException e) {
                Log.e("test", "文件创建失败:\t" + e.getMessage());
            }
        }
//        Log.e("test", "文件:\t" + file.getAbsolutePath());
        return file;
    }

    //处理相册中的图片旋转问题
    public Bitmap rotateBitmap(String path, Bitmap bitmap) {
        int degree = readPictureDegree(path);
        return rotateBitmap(bitmap, degree);
    }

    private int readPictureDegree(String path) {
        int degree = 0;
        try {
            ExifInterface exifInterface = new ExifInterface(path);
            int orientation = exifInterface.getAttributeInt(
                    ExifInterface.TAG_ORIENTATION,
                    ExifInterface.ORIENTATION_NORMAL);
            switch (orientation) {
                case ExifInterface.ORIENTATION_ROTATE_90:
                    degree = 90;
                    break;
                case ExifInterface.ORIENTATION_ROTATE_180:
                    degree = 180;
                    break;
                case ExifInterface.ORIENTATION_ROTATE_270:
                    degree = 270;
                    break;
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return degree;
    }

    private Bitmap rotateBitmap(Bitmap bitmap, int rotate) {
        if (bitmap == null)
            return null;

        int w = bitmap.getWidth();
        int h = bitmap.getHeight();

        // Setting post rotate to 90
        Matrix mtx = new Matrix();
        mtx.postRotate(rotate);
        return Bitmap.createBitmap(bitmap, 0, 0, w, h, mtx, true);
    }

    //将Uri图片的内容复制到file上,成功返回Bitmap,错误返回null
    public Bitmap writeFile(ContentResolver cr, File file, Uri uri,
                            String photoPath) {
        Bitmap bitmap = null;//位图
        boolean result = true;//判断位图是否生成正确
        try {
            FileOutputStream fout = new FileOutputStream(file);
            bitmap = BitmapFactory.decodeStream(cr.openInputStream(uri), null, AssetsUtils.getInstance().getOptionsRGB_565());
            int bitmapWidth = bitmap.getWidth();
            int bitmapHeight = bitmap.getHeight();
            // 缩放图片的尺寸比例
            float scale = (float) BITMAP_WIDTH / bitmapWidth;
            Matrix matrix = new Matrix();
            matrix.postScale(scale, scale);
            // 产生缩放后的Bitmap对象
            bitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmapWidth,
                    bitmapHeight, matrix, false);
            if (photoPath != null && !photoPath.equals("")) {
                try {
                    // 处理图片旋转问题
                    bitmap = rotateBitmap(photoPath, bitmap);
                } catch (Exception e) {
                    // TODO: handle exception
                    Log.e("test", "writeFile图片选择异常" + e.getMessage());
                }
            }
            // 压缩图片，并且保存文件
            bitmap.compress(Bitmap.CompressFormat.JPEG, quality, fout);// 80是压缩率，表示压缩20%;取值范围在0~100，代表质量
            try {
                fout.flush();
                fout.close();
            } catch (IOException e) {
                e.printStackTrace();
                result = false;
            }
        } catch (FileNotFoundException e) {
            Log.e("test", "相册图片异常1" + e.getMessage());
            result = false;
        } catch (Exception e) {
            Log.e("test", "相册图片异常2" + e.getMessage());
        }
        if (result) {
            return bitmap;
        }
        return null;
    }

    //获取压缩图片，并且保存该压缩图片到本地文件。返回objects[0] 是文件,objects[1]是位图。错误返回null
    public Object[] getScaleBitmap(String path, Bitmap bm, float width,
                                   int quality) {
        if (bm == null) {
            return null;
        }
        try {
            int bitmapWidth = bm.getWidth();
            int bitmapHeight = bm.getHeight();
            // 缩放图片的尺寸比例
            float scale = (float) width / bitmapWidth;
            Matrix matrix = new Matrix();
            matrix.postScale(scale, scale);
            // 产生缩放后的Bitmap对象
            bm = Bitmap.createBitmap(bm, 0, 0, bitmapWidth, bitmapHeight,
                    matrix, false);
            File myCaptureFile = new File(path);
            FileOutputStream out = new FileOutputStream(myCaptureFile);
            // 压缩图片，并且保存文件
            bm.compress(Bitmap.CompressFormat.JPEG, quality, out);// 30是压缩率，表示压缩70%;取值范围在0~100，代表质量
            Object[] objects = new Object[]{myCaptureFile, bm};
            return objects;
        } catch (Exception e) {
            Log.e("test", "图片压缩异常:\t" + e.getMessage());
        }
        return null;
    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        // TODO Auto-generated method stub
        if (requestCode == Activity.DEFAULT_KEYS_DISABLE) {
            //图片剪辑,不需要判斷data是否為空。因為是剪輯。data本來就是空的。
            try {
                Bitmap bitmap = BitmapFactory.decodeStream(this.getContentResolver().openInputStream(cropUri), null, AssetsUtils.getInstance().getOptionsRGB_565());
                if (bitmap != null) {
                    if (cropFile != null && cropFile.exists()) {
                        onCropResult(cropFile, bitmap);
                    } else {
                        File file = new File(cropUri.getPath());
                        FileOutputStream out = new FileOutputStream(file);
                        bitmap.compress(Bitmap.CompressFormat.JPEG, quality, out);//保存压缩后的位图
                        onCropResult(file, bitmap);
                    }
                } else {
                    onFailure("图片剪辑位图为null");
                }
            } catch (Exception e) {
                onFailure("图片剪辑异常:\t" + e.getMessage());
            }
        }
        if (requestCode == Activity.DEFAULT_KEYS_SHORTCUT || requestCode == Activity.DEFAULT_KEYS_DIALER) {
            //相册或相机
            try {
                Bitmap bm = null;
                File file = null;
                // 相册
                if (requestCode == Activity.DEFAULT_KEYS_SHORTCUT && data != null
                        && data.getData() != null) {// 验证返回数据不为null
                    Uri uri = data.getData();
                    String photoPath = null;
                    try {
                        photoPath = getPhotoPath(this, data);// 获取相册图片路径
                    } catch (Exception e) {
                        // TODO: handle exception
                        Log.e("test", "相册图片路径获取失败" + e.getMessage());
                    }
                    // 创建新图片
                    file = createFile(getAppCaclePath());
                    bm = writeFile(this.getContentResolver(),
                            file, uri, photoPath);// 将Uri图片的内容复制到file上
                }
                // 相机
                else if (requestCode == Activity.DEFAULT_KEYS_DIALER) {
                    // 获取图片路径
                    String path = fileUri.getPath();
                    //Log.e("test", "路径；\t" + path);
                    bm = BitmapFactory.decodeStream(this.getContentResolver().openInputStream(fileUri), null, AssetsUtils.getInstance().getOptionsRGB_565());
                    //Log.e("test", "位图:\t" + bm + "\t宽:\t" + bm.getWidth() + "\t高:\t" + bm.getHeight());
                    // 处理图片旋转
                    bm = rotateBitmap(path, bm);
                    // 创建新图片
                    file = createFile(getAppCaclePath());
                    // 图片压缩
                    Object[] objects = getScaleBitmap(file.getAbsolutePath(), bm, BITMAP_WIDTH, quality);
                    file = (File) objects[0];
                    bm = (Bitmap) objects[1];
                    //相机拍照的图片有的设备会保存起来，而有的则不会。高版本的一般都不会保存。所以靠不住。建议使用自己的保存文件。删除拍照的文件。
                    if (!path.trim().equals(file.getAbsolutePath().trim())) {//确保拍照文件和保存文件，不是同一个文件
                        File file1 = new File(path);
                        if (file1.exists()) {//不管大小，只要存在就删除
                            //Log.e("test","删除\t"+file1.getAbsolutePath()+"\t大小:\t"+file1.length());
                            file1.delete();//删除原有拍照的图片。
                        }
                    }
                }
                // 设置图片
                if (bm != null) {
                    onSuccess(file, bm);// 回调函数，返回图片路径
                } else {
                    onFailure("位图Bitmap为null");
                }
            } catch (Exception e) {
                onFailure("图片获取异常:\t" + e.getMessage());
            }
        }
        if (requestCode == VIDEO_PHOTO && resultCode == RESULT_OK && data != null
                && data.getData() != null) {
            //本地视频
            Uri uri = data.getData();
            //uri.getPath() 这个路径不行。靠不住。不要用。
            Cursor cursor = getContentResolver().query(uri, null, null,
                    null, null);
            if (cursor != null) {
                cursor.moveToFirst();
                // 视频ID:MediaStore.Audio.Media._ID
                //int videoId = cursor.getInt(cursor.getColumnIndexOrThrow(MediaStore.Video.Media._ID));
                // 视频标题【没有后缀】：MediaStore.Audio.Media.TITLE
                // 视频名称【文件名带后缀】：MediaStore.Audio.Media.DISPLAY_NAME，这个无论是相册里的视频，还是本地视频里的视频都能过获取。
                String fileName = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Video.Media.DISPLAY_NAME));//亲测能够获取。
                //Log.e("test","名称:\t"+fileName);
                String videoPath = null;
                try {
                    // 视频路径：MediaStore.Audio.Media.DATA。相册里面的视频可以获取。但是本地视频里的视频，路径无法获取。
                    videoPath = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Video.Media.DATA));//需要SD权限才能操作。
                } catch (Exception e) {
                    videoPath = null;
                    //Log.e("test", "本地视频路径获取失败:\t" + e.getMessage());
                }
                File file = null;
                try {
                    if (videoPath != null && judgeStorage(this)) {
                        //Log.e("test", "具备SD卡权限");
                        file = new File(videoPath);//直接对原视频进行读取。
                    } else {
                        //无法对原视频读取时，就对流进行操作。
                        //虽然我们获取得到了视频的路径，但是如果我们没有SD卡读取权限的话，仍然无法操作视频。但是我们可以直接对流进行操作啊。相册也是这么干的。所以才不需要SD卡的权限。
                        //将流转化为File文件。
                        file = FileUtils.getInstance().inputSteamToFile(getContentResolver().openInputStream(uri), getAppCaclePath(), fileName);
                    }
                } catch (Exception e) {
                    Log.e("test", "uri获取流异常:\t" + e.getMessage());
                }
                //Log.e("test", "文件是否存在:\t" + file.exists() + "\t路径:\t" + file.getPath() + "\t大小：\t" + file.length());
                MediaMetadataRetriever media = new MediaMetadataRetriever();
                try {
                    media.setDataSource(file.getAbsolutePath());
                    //Log.e("test","绝对路径:\t"+file.getAbsolutePath());
                } catch (Exception e) {
                    file = null;
                    Log.e("test", "media.setDataSource()异常:\t" + e.getMessage());
                }
                if (file == null) {
                    return;
                }
                String time = media.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION);// 取得视频的长度(单位为毫秒)
                int seconds = Integer.valueOf(time) / 1000;//转化为秒。
                Double size = NumberUtils.getInstance().getDataSizeMB(file.length());
                //Bitmap bitmap = media.getFrameAtTime(seconds*1000*1000);//返回最后一张。getFrameAtTime()单位是us,微秒。
                //Bitmap bitmap = media.getFrameAtTime(0);//返回第一张。
                Bitmap bitmap = media.getFrameAtTime();//返回第一张。默认就是第一张。
                VideoModel videoModel = new VideoModel();
                videoModel.setFile(file);
                videoModel.setName(file.getName());
                videoModel.setPath(file.getAbsolutePath());
                videoModel.setTime(seconds + "");
                videoModel.setSize(size + "");
                videoModel.setFirstBitmap(bitmap);
                onCameraVideoResult(videoModel);//回调
                //Log.e("test", "" + videoModel.toString());
            }
        }
        //相机视频拍摄
        if (resultCode == Activity.RESULT_OK && requestCode == VIDEO_CAPTURE && data != null
                && data.getData() != null) {
            if (cameraVideoFile == null || !cameraVideoFile.exists()) {
                return;
            }
            MediaMetadataRetriever media = new MediaMetadataRetriever();
            media.setDataSource(cameraVideoFile.getAbsolutePath());
            String time = media.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION);// 取得视频的长度(单位为毫秒)
            int seconds = Integer.valueOf(time) / 1000;//转化为秒。
            Double size = NumberUtils.getInstance().getDataSizeMB(cameraVideoFile.length());
            //Bitmap bitmap = media.getFrameAtTime(seconds*1000*1000);//返回最后一张。getFrameAtTime()单位是us,微秒。
            //Bitmap bitmap = media.getFrameAtTime(0);//返回第一张。
            Bitmap bitmap = media.getFrameAtTime();//返回第一张。默认就是第一张。
            VideoModel videoModel = new VideoModel();
            videoModel.setFile(cameraVideoFile);
            videoModel.setName(cameraVideoFile.getName());
            videoModel.setPath(cameraVideoFile.getAbsolutePath());
            videoModel.setTime(seconds + "");
            videoModel.setSize(size + "");
            videoModel.setFirstBitmap(bitmap);
            onCameraVideoResult(videoModel);//回调
            //Log.e("test", "" + videoModel.toString());
        }
        super.onActivityResult(requestCode, resultCode, data);
    }

    //裁剪成功后，回调，返回文件和位图
    public void onCropResult(File file, Bitmap bitmap) {
    }

    //相册或拍照成功后，回调，返回文件和位图
    public void onSuccess(File file, Bitmap bitmap) {
    }

    //位图为null,或异常时回调【相册，拍照，裁剪失败都会回调】
    public void onFailure(String result) {
    }

    //相机视频拍摄成功后，回调。本地视频选择成功后，也回调这个。即本地视频还是拍摄视频都回调这个。
    public void onCameraVideoResult(VideoModel videoModel) {
    }

    //权限请求成功回调，返回参数为属于什么类型的权限申请。
    public void onRequestPermissionsSuccess(int perMissionMode) {
    }


    //注意：申请权限之前，一定要在清单里注册一下。没有注册权限，是无法申请权限的。没有注册只会返回失败，不会弹出权限询问框。
    //权限数组
    private final static String DANGEROUS_PERMISSION[] = new String[]{
            Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.READ_PHONE_STATE, Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.CAMERA, Manifest.permission.RECORD_AUDIO};
    private final static String DANGEROUS_PERMISSION_CAMERA[] = new String[]{Manifest.permission.CAMERA};//相机
    private final static String DANGEROUS_PERMISSION_STORAGE[] = new String[]{Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE};//SD卡读写
    private final static String DANGEROUS_PERMISSION_RECORD[] = new String[]{Manifest.permission.RECORD_AUDIO};//录音
    private final static String DANGEROUS_PERMISSION_READ_PHONE_STATE[] = new String[]{Manifest.permission.READ_PHONE_STATE};//用于调用 JNI ,及读取设备的权限，如手机设备号
    // requestCode 权限请求码
    public final static int READ_PHONE_STATE_REQUEST_CODE = 11;//权限请求标志

    protected int perMissionMode = 0;//当前权限申请的标识。默认为相机拍照。
    protected int perMissionModeALL = 5;//以下所有权限的集合。
    protected int perMissionModeCamera = 0;//相机拍照权限申请标识。图片,相机拍照和拍摄都需要相机权限。
    protected int perMissionModeVideo = 1;//相机拍摄权限申请标识。视频
    protected int perMissionModeStorage = 2;//SD卡权限申请标识。
    protected int perMissionModeRecording = 3;//录音权限申请标识。
    protected int perMissionModeReadPhoneState = 4;//手机状态权限申请，如手机设备号等。

    //注意，如果该权限已经申请成功。再次调用权限申请，不会弹出权限申请窗口。会直接返回成功回调。

    //一般的权限申请，手机信息，存储卡权限。相机，录音。
    public boolean requestPermissionsALL(Activity activity) {
        if (Build.VERSION.SDK_INT >= 23) {//Android6.0权限申请
            perMissionMode = perMissionModeALL;
            // 权限已经授予,直接初始化
            if (ActivityCompat.checkSelfPermission(activity,
                    Manifest.permission.READ_PHONE_STATE) != PackageManager.PERMISSION_GRANTED
                    || ActivityCompat.checkSelfPermission(activity,
                    Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED
                    || ActivityCompat.checkSelfPermission(activity,
                    Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED
                    || ActivityCompat.checkSelfPermission(activity,
                    Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED
                    || ActivityCompat.checkSelfPermission(activity,
                    Manifest.permission.RECORD_AUDIO) != PackageManager.PERMISSION_GRANTED) {
                // 申请权限
                ActivityCompat.requestPermissions(activity, DANGEROUS_PERMISSION, READ_PHONE_STATE_REQUEST_CODE);
                return false;
            }
        }
        return true;
    }

    //相机权限请求，true通过，false 会弹出权限请求窗口。【6.0以上才需要】
    public boolean requestPermissionsCamera(Activity activity) {
        if (getApplicationInfo().targetSdkVersion >= 23) {
            if (ActivityCompat.checkSelfPermission(activity,
                    Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {//判断权限是否已授权。没有授权再发生请求回调。已经授权，就不再申请。
                // 申请权限【sdk6.0即以上才有效。targetSdkVersion23及以上才有效。】
                ActivityCompat.requestPermissions(activity, DANGEROUS_PERMISSION_CAMERA, READ_PHONE_STATE_REQUEST_CODE);
                return false;
            }
        } else {
            //6.0以下。第一次会弹出系统询问权限框。后面就不会弹了。
            Camera mCamera = null;
            try {
                mCamera = Camera.open();//第一次会弹出系统询问权限框【是线程阻塞的。 询问弹框消失了才会继续向下执行。】
                Camera.Parameters mParameters = mCamera.getParameters();
                mCamera.setParameters(mParameters);
            } catch (Exception e) {
                Snackbarmake("需要开启相机权限");
                return false;
            }
            if (mCamera != null) {
                try {
                    mCamera.release();
                } catch (Exception e) {
                    Snackbarmake("需要开启相机权限");
                    return false;
                }
            }
        }
        return true;
    }

    //SD卡权限申请
    public boolean requestPermissionsStorage(Activity activity) {
        perMissionMode = perMissionModeStorage;//当前SD卡申请标志
        if ((ActivityCompat.checkSelfPermission(activity,
                Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) || (ActivityCompat.checkSelfPermission(activity,
                Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED)) {
            // 申请权限
            ActivityCompat.requestPermissions(activity, DANGEROUS_PERMISSION_STORAGE, READ_PHONE_STATE_REQUEST_CODE);
            return false;
        }
        return true;
    }

    //录音权限申请
    public boolean requestPermissionsRecording(Activity activity) {
        perMissionMode = perMissionModeRecording;
        if (ActivityCompat.checkSelfPermission(activity,
                Manifest.permission.RECORD_AUDIO) != PackageManager.PERMISSION_GRANTED) {
            // 申请权限
            ActivityCompat.requestPermissions(activity, DANGEROUS_PERMISSION_RECORD, READ_PHONE_STATE_REQUEST_CODE);
            return false;
        }
        return true;
    }

    //手机状态权限申请，如手机设备号等。
    public boolean requestPermissionsReadPhoneState(Activity activity) {
        perMissionMode = perMissionModeReadPhoneState;
        if (ActivityCompat.checkSelfPermission(activity,
                Manifest.permission.READ_PHONE_STATE) != PackageManager.PERMISSION_GRANTED) {
            // 申请权限
            ActivityCompat.requestPermissions(activity, DANGEROUS_PERMISSION_READ_PHONE_STATE, READ_PHONE_STATE_REQUEST_CODE);
            return false;
        }
        return true;
    }

    //判定是否具备SD卡手机存储权限。
    public boolean judgeStorage(Activity activity) {
        if ((ActivityCompat.checkSelfPermission(activity,
                Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) || (ActivityCompat.checkSelfPermission(activity,
                Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED)) {
            return false;//没有权限
        }
        return true;//有权限
    }

    //判断权限数组是否全部都授权，有一个没有授权都返回false。全部授权才返回true
    public boolean judgePermission(int[] grantResults) {
        boolean b = true;
        for (int i = 0; i < grantResults.length; i++) {
            if (grantResults[i] != PackageManager.PERMISSION_GRANTED) {
                b = false;//没有授权
            }
        }
        return b;
    }

    public static View SnakbarView = null;//顶部snackbar容器，防止snackbar不显示。

    @Override
    protected void onDestroy() {
        super.onDestroy();
        SnakbarView = null;
    }

    public View getContent() {
        if (SnakbarView != null) {
            return SnakbarView;
        }
        return getWindow().getDecorView().findViewById(android.R.id.content);
    }

    //消息提示
    public void Snackbarmake(String info) {
        Snackbar snackbar = Snackbar.make(getContent(), info, Snackbar.LENGTH_LONG)
                .setAction("立即设置", new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        Uri packageURI = Uri.parse("package:" + getPackageName());
                        Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS, packageURI);
                        startActivity(intent);//跳转权限设置界面。基本上通用。小米是肯定行的。android6.0基本都可以。
                    }
                });
        View snackView = snackbar.getView();
        //int textSize= (int) (UtilProportion.getInstance(this).adapterInt(24) * UtilProportion.getInstance(this).getTextProportion()/ UtilProportion.getInstance(this).getDensity());
        snackView.setBackgroundColor(Color.parseColor("#3E4EB8"));//蓝色背景
        //snackView.setBackgroundResource(R.drawable.shape_drawable_snackbar);
        TextView snackbar_text = (TextView) snackView.findViewById(R.id.snackbar_text);
        snackbar_text.setTextColor(Color.parseColor("#ffffff"));//设置通知文本的颜色，白色
        //snackbar_text.setTextSize(textSize);
        TextView snackbar_action = (TextView) snackView.findViewById(R.id.snackbar_action);
        snackbar_action.setTextColor(Color.parseColor("#FF3B80"));//点击文本的颜色,绯红
        //snackbar_action.setTextSize(textSize);
        //snackbar_action.setBackground(null);
        snackbar_action.setBackgroundDrawable(null);
        snackbar.show();
    }

    //权限回调，只要调用了ActivityCompat.requestPermissions()就一定会回调以下方法。
    //不管用户是拒绝还是选择再也不提示，都会回调以下方法。
    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {//grantResults就是之前申请的权限数组。一模一样。权限的数量和顺序都一模一样。
        if (requestCode == READ_PHONE_STATE_REQUEST_CODE && grantResults.length > 0) {//一定要判断一下grantResults是否大于0，防止他脑抽。
            //if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {//PackageManager.PERMISSION_GRANTED 授权成功
            if (judgePermission(grantResults)) {
                // 权限授予成功
                onRequestPermissionsSuccess(perMissionMode);
                Log.e("test", "授权成功:\t" + grantResults.length);
            } else {
                //权限申请失败
                String info = null;
                if (perMissionMode == perMissionModeCamera || perMissionMode == perMissionModeVideo) {
                    info = "需要开启相机权限";
                } else if (perMissionMode == perMissionModeStorage) {
                    info = "需要开启手机存储权限";
                } else if (perMissionMode == perMissionModeRecording) {
                    info = "需要开启手机录音权限";
                } else if (perMissionMode == perMissionModeReadPhoneState) {
                    info = "需要开启手机信息权限";
                } else if (perMissionMode == perMissionModeALL) {
                    info = "权限申请失败";
                }
                Log.e("test", "授权失败:\t" + info);
                if (info != null) {
                    Snackbarmake(info);
                }
            }
        } else {
            super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        }
    }


    //视频实体类
    public static class VideoModel {
        File file;//视频文件
        String path;//视频路径，绝对路径。包括文件的后缀名。
        String name;//文件名。不包括路径。只包括文件名。同样包括文件名后缀。
        String time;//视频时长。单位秒。
        String size;//文件大小。单位MB
        Bitmap firstBitmap;//视频第一张位图。

        public VideoModel() {
        }

        @Override
        public String toString() {
            return "路径:\t" + path + "\t文件名:\t" + name + "\t大小:\t" + size + "\t视频时长:\t" + time + "\t第一张位图大小:\t" + firstBitmap.getByteCount();
        }

        public File getFile() {
            return file;
        }

        public void setFile(File file) {
            this.file = file;
        }

        public String getPath() {
            return path;
        }

        public void setPath(String path) {
            this.path = path;
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public String getTime() {
            return time;
        }

        public void setTime(String time) {
            this.time = time;
        }

        public Bitmap getFirstBitmap() {
            return firstBitmap;
        }

        public void setFirstBitmap(Bitmap firstBitmap) {
            this.firstBitmap = firstBitmap;
        }

        public String getSize() {
            return size;
        }

        public void setSize(String size) {
            this.size = size;
        }
    }

}
